using UnityEngine;
using System;
using System.ComponentModel;
using Newtonsoft.Json;

namespace CalmNine.Framework
{
    public class PlayerPrefsCustomVal<T> : EventVal<T>, IGameSave where T : class
    {
        private readonly string mSaveKey;
        private INotifyPropertyChanged mCurrentNotifier;

        private void UnsubscribePropertyChanged()
        {
            if (mCurrentNotifier != null)
            {
                mCurrentNotifier.PropertyChanged -= OnPropertyChanged;
                mCurrentNotifier = null;
            }
        }

        private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            // 触发值变更事件，这会间接调用已注册的SaveValue方法
            this.mOnValueChanged(mValue);
        }

        private void SaveValue(T value)
        {
            try
            {
                string json = JsonConvert.SerializeObject(value);
                PlayerPrefs.SetString(mSaveKey, json);
            }
            catch (Exception e)
            {
                Debug.LogError($"Failed to serialize data for key {mSaveKey}: {e.Message}");
            }
        }

        protected override void SetValue(T newValue)
        {
            UnsubscribePropertyChanged();
            base.SetValue(newValue);
            
            if (newValue is INotifyPropertyChanged notifier)
            {
                mCurrentNotifier = notifier;
                notifier.PropertyChanged += OnPropertyChanged;
            }
        }

        public PlayerPrefsCustomVal(string saveKey, T defaultValue = default)
        {
            mSaveKey = saveKey;
            
            // 从PlayerPrefs加载序列化的数据
            string savedData = PlayerPrefs.GetString(saveKey, string.Empty);
            if (!string.IsNullOrEmpty(savedData))
            {
                try
                {
                    // 尝试反序列化数据
                    mValue = JsonUtil.ConvertToObj<T>(savedData);
                }
                catch (Exception e)
                {
                    Debug.LogError($"Failed to deserialize data for key {saveKey}: {e.Message}");
                    mValue = defaultValue;
                }
            }
            else
            {
                mValue = defaultValue;
                if (defaultValue != null)
                {
                    SaveValue(defaultValue);
                }
            }

            // 初始订阅对象的属性变更事件
            if (mValue is INotifyPropertyChanged notifier)
            {
                mCurrentNotifier = notifier;
                notifier.PropertyChanged += OnPropertyChanged;
            }

            // 注册值变更事件，当值发生变化时自动序列化并保存
            this.Register(SaveValue);
        }
    }
}
